﻿using System;
using System.Collections.Generic;
using ESRI.ArcGIS.Client;
using Cowi.ImageManager.WebServices;
using ESRI.ArcGIS.Client.Geometry;
using System.Text;

namespace Silverroute
{
    /// <summary>
    /// TiledMapServiceLayer wrapper for a Cowi Image Manager Tile Server Pyramid
    /// </summary>
    public class CIMTiledMapServiceLayer : TiledMapServiceLayer 
    {
		private PyramidInfo pyramidInfo;
		private string url;

        //COWI code to transform COWI pyramids to ESRI pyramids.
		public CIMTiledMapServiceLayer(PyramidInfo pyramidInfo, string url)
		{
			this.url = url;
			this.pyramidInfo = pyramidInfo;

            FullExtent = new Envelope();
            FullExtent.XMin = pyramidInfo.offsetX;
            FullExtent.XMax = pyramidInfo.offsetX + pyramidInfo.baseWidth;
            FullExtent.YMin = pyramidInfo.offsetY - pyramidInfo.baseHeight;
            FullExtent.YMax = pyramidInfo.offsetY;
            FullExtent.SpatialReference = new SpatialReference(pyramidInfo.epsgCode);
			SpatialReference = FullExtent.SpatialReference;
			IsInitialized = true;
			TileInfo = new TileInfo();
			TileInfo.Height = pyramidInfo.tileSize;
			TileInfo.Width = pyramidInfo.tileSize;
			TileInfo.SpatialReference = SpatialReference;

			// Calculate bottom level resolution
			double res = pyramidInfo.baseWidth / (Math.Pow(2, pyramidInfo.levels) * pyramidInfo.tileSize);
			List<Lod> lods = new List<Lod>();
			for (int i = 0; i < pyramidInfo.levels+1 ; i++)
            {
            	Lod lod = new Lod();
				lod.Resolution = res;
				res = res*2;
				lods.Add(lod);
            }
			lods.Reverse();
			this.TileInfo.Lods = lods.ToArray();
			this.TileInfo.Origin = new MapPoint(this.FullExtent.XMin, this.FullExtent.YMax);
		}

        //We create the URL for the quadkey we need from the pyramid we want
		public override string GetTileUrl(int level, int row, int col)
		{
			System.Diagnostics.Debug.WriteLine(level + " " + col + " " + row);
			string QuadKey = TileXYToQuadKey(col, row, level);
			var uri = new Uri(url + "?quadkey=" + QuadKey + "&pyramid=" + pyramidInfo.name);
			return uri.ToString();
		}

		private static string TileXYToQuadKey(int tileX, int tileY, int levelOfDetail)
		{
			var quadKey = new StringBuilder();
			for (int i = levelOfDetail; i > 0; i--)
			{
				char digit = '0';
				int mask = 1 << (i - 1);
				if ((tileX & mask) != 0)
				{
					digit++;
				}
				if ((tileY & mask) != 0)
				{
					digit++;
					digit++;
				}
				quadKey.Append(digit);
			}
			return quadKey.ToString();
		}
	}
}
